/**
*@class Ai
*@brief ??? Samenvattende commentaar ???
*@author Naam
*@date 04-2011
*
* @section source Sources
* Hier komen de bestanden vanwaar de code informatie krijgt en in welke vorm.
*
* @section working What does the code
* Hier komt wat de code doet.
*
* @section destination Destination
* Hier staat welke code rechtstreeks gebruik maakt van deze code
*
*/


#include <stdio.h>
#include <cstdlib>
#include <cstdlib>
#include <stdio.h>
#include <iostream>
#include <exception>
#include <new>
#include <math.h>
#include "node.h"
#include "location.h"
#include "element.h"
#include  "math.h"

#define ABS(a) ((a)<0?-(a):a)
#define MIN(a, b)  (((a) < (b)) ? (a) : (b))
#define MAX(a, b)  (((a) > (b)) ? (a) : (b))
#define DIFF_DIST 25
#define MAX_DEPTH 11
#define GOAL 0		//if 0 enemy goal at (0,750)
			//else enemy goal at (1800,750)
#define ABS(a) ((a)<0?-(a):a)
#define MIN(a, b)  (((a) < (b)) ? (a) : (b))
#define MAX(a, b)  (((a) > (b)) ? (a) : (b))



#define FIELD_X 15
#define FIELD_Y 15
#define TRANSPONEERD 10

class Ai
{
public:
    /** Default constructor */
    Ai();
    /** Default destructor */
    ~Ai();


    /** @brief  Transforms the real coördinates to a simplified field
    *           Sets the rotation to be a multiple of 45°
    *           This is a supporting function, it should not be called in normal operation.
    *   @param  A location that needs to be transformed
    *   @return Returns the transformed location
    */
    Location transform(Location loc);



    /**  @brief Builds a cost matrix, applies dijkstra to find the shortest route.
    *    @param Own location (robot)
    *    @param Wanted Location (This can be find using the function next_location()  )
    *    @param integer flag, used to enable (1) or disable (0) cost matrix calculation.
    *           If disabled assume eaqual cost for every location.
    *    @return The next location of the robot
    */
    Location next_step(Location own, Location wanted, int flag);


    /**     @brief This algoritme contains the logic (or ai) that calculates the next optimal? position.
    *              Every robot can be in 3 diffrent states: support, attacking and defending.
    *              In the attacking and defending state, the best position is based uppon the value of the attack angle.
    *              The goal is to keep the attack angle low while defending and high while attacking.
    *              The minimum angle attack angle (shoot ball) will be find using real test.
    *              In the support role, the goal is to get the ball before the enemy robot gets it.
    *              If thats not possibel (own robot is further away) start de defend role en minimize the attack angle
    *       @param Ball location
    *       @param Own Robot location
    *       @param Enemy robot location
    *       @return The optimal location
    **/
    Location next_location(Location ball, Location own_robot, Location enemy_robot);


   	/**	@brief Calculates the step size in function of the distance towards the enmy goal
	*	small values for short distances large for a larger distance
	*	@param Current Element with location of own_robot etc ....
	**/
	int move_size(Element *CurrentN);

	/**	@brief Uses the minimax algorimthe to calculate the next position towards the optimal position
	*	for attacking.
	*	@param Current Element with the position of robot & enemy_robot
	*	@param diepte, startt at zero grow untill MAX_DEPTH
	*	@param step, the maximum distance the minimax algorimtme can travel in the next_step logic.

	**/
	void minimax_a(Element *CurrentN, int depth, int step);

	/**	@brief Uses the minimax algorimthe to calculate the next position towards the optimal position
	*	for defending.
	*	@param Current Element with the position of robot & enemy_robot
	*	@param diepte, startt at zero grow untill MAX_DEPTH
	*	@param step, the maximum distance the minimax algorimtme can travel in the next_step logic.

	**/
	int minimax_d(Element *CurrentN, int depth, int step);







	/**	@brief Calculates the new position in function of the step_size and the current rotation.
	*	The flag variabels decides if the own or enemy robot location needs updating.
	*	@param Current Element
	*	@param step_size
	*	@param flag
	**/
	void adjustlocation(Element *node, int step, int flag);


	/**	@brief A simple function to adjust the current rotation with step_size (can be negative)
	*	The flag variabels decides if the own or enemy robot location needs updating.
	*	@param Current Element
	*	@param step_size
	*	@param flag
	**/
	void adjust_angle(Element *node,int step, int flag);


	/**	@brief Calculates the angle between 2 points in our playfield
	*	this function return the angle with respect to the origin in the upper left corner
	*	@param from X cordinaat
	* 	@param from Y cordinaat
	*	@param to X cordinaat
	* 	@param to Y cordinaat
	*	@return float angle
	**/
	float angle( int from_x, int from_y, int to_x, int to_y);

	/**	@brief This function checks the parents of the Current Node
		If one of the parents is about the same location and rotation we return 1
		This is used to stop the growth of this subtree. ( == Exelent preformance booster )
		@param Element Current
		return 1 or 0
	**/
	int check_parents(Element *CurrentN);


	/**	@brief This function calculates the cost of a certain locations this with the definding tactics.
	*	The cost in caluclated with with respect to: Current_angle, Optimal_angle and a parabolic function with the distance to the enemy goal as value
	*	The cost is recored on the Elment (node ? )
	*	Element Current Element
	**/
	//void calculate_cost_d(Element *CurrentN);

	/**	@brief This function calculates the cost of a certain locations this with the definding tactics.
	*	The cost in caluclated with with respect to: Current_angle, Optimal_angle and a parabolic function with the distance to the enemy goal as value
	*	The cost is recored on the Elment (node ? )
	*	Element Current Element
	**/
	void calculate_cost_a(Element *CurrentN);

	/**	@brief This functions takes the KopElement as argument and will delete itself and every other Element beneath.
	*	Returns 0 when this functions is done.
	*	@param Element KopElement
	*	@return int 0
	**/
	int del_element(Element *CurrentN);


	/**	@brief calculates the distance between 2 points
	*	@param Point 1 X coordinaat
	*	@param point 2 X Coordinaat
	*	@param Point 1 Y coordinaat
	*	@param point 2 Y Coordinaat
	*	@return float distance
	**/
	float dist(int x1, int y1, int x2, int y2);


	/**	@brief parabolic function. used to design an attack patterns
	*	@param Float dist : This is the distance from own_robot to enemy goal
	*	@return Float value : function based value
	**/
	float parabool(float dist);

};

